home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!ogicse!zephyr.ens.tek.com!tekred!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v11i076: bt - Broken Throne, multiplayer realtime conquest game, Part02/02
- Message-ID: <6596@tekred.CNA.TEK.COM>
- Date: 21 Nov 90 20:16:59 GMT
- Sender: news@tekred.CNA.TEK.COM
- Lines: 520
- Approved: billr@saab.CNA.TEK.COM
- Posted: Wed Nov 21 12:16:59 1990
-
- Submitted-by: Tom Boutell <boutell@freezer.it.udel.edu>
- Posting-number: Volume 11, Issue 76
- Archive-name: bt/Part02
- Environment: INET sockets, curses
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 2 (of 2)."
- # Contents: Makefile interface.c types.h
- # Wrapped by billr@saab on Wed Nov 21 12:13:26 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(306 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- Xbtclient: client.o pack.o
- X cc client.o pack.o -o btclient -ltermcap -lcurses -ltermlib
- X
- Xbtserver: bt.o pack.o interface.o
- X cc bt.o pack.o interface.o -o btserver
- X
- Xclient.o: client.c
- X cc -c -g client.c
- Xpack.o: pack.c
- X cc -c -g pack.c
- Xinterface.o: interface.c
- X cc -c -g interface.c
- Xbt.o: bt.c
- X cc -c -g bt.c
- END_OF_FILE
- if test 306 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'interface.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'interface.c'\"
- else
- echo shar: Extracting \"'interface.c'\" \(8905 characters\)
- sed "s/^X//" >'interface.c' <<'END_OF_FILE'
- X
- X/* interface.c: Socket communications support& medium- level message
- X * passing functions. Copyright (C) 1990 Tom Boutell on original portions.
- X * All low- level socket code drawn with appreciation from:
- X * SOCK.C
- X * Copyright (C)1989 Dr Evil Laboratories
- X * This code written by Ray Moody, Roy Riggs, Mitch Adler,
- X * Bill Burdick, and Steven Grady
- X * No one makes any guarantees about anything. This file maybe
- X * freely distributed and modified as long as this header remains intact.
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/time.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <string.h>
- X#include <ctype.h>
- X#include <signal.h>
- X#include <netdb.h>
- X#include <varargs.h>
- X
- X#include "types.h"
- X#include "pack.h"
- X#include "bt.h"
- X#include "interface.h"
- X
- X#define DEBUG
- X#undef DEBUG
- X#ifdef DEBUG
- X#define debug printf
- X#else
- X#define debug 0+
- X#define perror 0+
- X#endif
- X
- X#define SECONDSLIMIT 0L
- X#define MICROSECONDSLIMIT 1L
- X
- X#define LINE_LEN 1024
- X#define LOST_CARRIER_MSG "F"
- X
- X#define NONE (fd_set *) NULL
- X#define NEVER (struct timeval *) NULL
- X#define IGNORE (struct sockaddr *) NULL
- X
- Xfd_set active;
- Xstruct sockaddr_in sc_in;
- Xint s;
- Xchar cur_input[LINE_LEN];
- Xchar *curhostname = "";
- Xint playerids[20];
- Xchar outputline[256];
- Xvoid setupinterface() {
- X int current;
- X init_socket(2727);
- X playertext=(outputline+1);
- X for (current=1; (current<=totalplayers); current++) {
- X playerids[current]=new_player(0);
- X players[current].live=1;
- X printf("Player %d has joined.\n",current);
- X outputline[0]=_YOUARE;
- X outputline[1]=64+current;
- X outputline[2]=0;
- X w_p(playerids[current],outputline,strlen(&outputline[0])+1);
- X }
- X}
- X
- Xvoid tellplayer(player)
- X int player;
- X{
- X outputline[0]=_TEXT;
- X w_p(playerids[player],outputline,strlen(&outputline[0])+1);
- X}
- X
- Xvoid broadcast(messagetype,details)
- X char messagetype;
- X void* details;
- X{
- X location where;
- X int thisplayer;
- X int current;
- X outputline[0]=messagetype;
- X switch (messagetype) {
- X
- X case _HEXSTATUS:
- X where=*(location*)details;
- X outputline[1]=64+where.x;
- X outputline[2]=64+where.y;
- X outputline[3]=64+map[where.x][where.y].terrain;
- X packint(4,map[where.x][where.y].population);
- X packint(7,map[where.x][where.y].lastuse);
- X packint(10,map[where.x][where.y].troops);
- X outputline[13]=map[where.x][where.y].owner+64;
- X outputline[14]=NULL;
- X break;
- X case _PLAYERSTATUS:
- X thisplayer=*(int*)details;
- X outputline[1]=thisplayer+64;
- X packint(2,players[thisplayer].action);
- X packint(5,players[thisplayer].hexes);
- X packint(8,players[thisplayer].troops);
- X packint(11,players[thisplayer].population);
- X packint(14,players[thisplayer].citadels);
- X outputline[17]=players[thisplayer].start.x+64;
- X outputline[18]=players[thisplayer].start.y+64;
- X outputline[19]=NULL;
- X break;
- X case _PLAYERDEAD:
- X thisplayer=*(int*)details;
- X outputline[1]=thisplayer+64;
- X outputline[2]=NULL;
- X break;
- X case _ACTION:
- X outputline[1]=NULL;
- X break;
- X case _STARTUP:
- X outputline[1]=totalplayers+64;
- X outputline[2]=NULL;
- X break;
- X case _TEXT:
- X strcpy(&outputline[1],(char*) details);
- X break;
- X case _END:
- X outputline[1]=NULL;
- X }
- X for (current=0; (current<=totalplayers); current++) {
- X if (outputline[0]==_END) {
- X }
- X if (players[current].live) {
- X w_p(playerids[current],outputline,strlen(outputline)+1);
- X }
- X }
- X}
- X
- Xint getrequest(thisplayer,requesttype,specific)
- X int* thisplayer;
- X char* requesttype;
- X char* specific;
- X{
- X char* received;
- X static int sweep;
- X int oldsweep;
- X sweep++;
- X if ((sweep>totalplayers) || (sweep<=0))
- X sweep=1;
- X oldsweep=sweep;
- X while (players[sweep].live==0) {
- X sweep++;
- X if (sweep>totalplayers)
- X sweep=1;
- X if (sweep==oldsweep)
- X return 0;
- X }
- X received=read_player(playerids[sweep]);
- X *thisplayer=sweep;
- X if (*received==NULL)
- X return 0;
- X *requesttype=received[0];
- X strcpy(specific,(received+=1));
- X return 1;
- X }
- X
- X
- Xvoid shutdowninterface() {
- X disconnect_all();
- X}
- X
- X
- X/* - PD Socket code begins here.
- X * init_socket() - intialize our socket, port is the port number to use
- X * call this once at the beginning of your code
- X */
- X
- Xint init_socket(port)
- X int port;
- X{
- X setbuf(stdout, (char *)0);
- X if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- X perror("socket");
- X return 0;
- X }
- X sc_in.sin_family = AF_INET;
- X sc_in.sin_addr.s_addr = INADDR_ANY;
- X sc_in.sin_port = htons((u_short) port);
- X if (bind(s, (struct sockaddr *) &sc_in, sizeof(sc_in)) < 0) {
- X perror("bind");
- X return 0;
- X }
- X if (listen(s, 5) < 0) {
- X perror("listen");
- X return 0;
- X }
- X
- X FD_ZERO(&active);
- X
- X return 1;
- X}
- X
- X
- X/*
- X * disconnect_all() - throws everyone off
- X */
- X
- Xint disconnect_all()
- X{
- X register int i;
- X
- X for (i = 0; i < FD_SETSIZE; i++) {
- X if (FD_ISSET(i, &active))
- X (void) disconnect(i);
- X }
- X return 1;
- X}
- X
- X
- X/*
- X * shut-down -- kills all connections and exits the pgm
- X */
- X
- Xint shut_down()
- X{
- X (void) disconnect_all();
- X exit(0);
- X}
- X
- X
- X/* hostfrom() - returns a string containing an ascii name for the host
- X * that the passed socket s is connected to. Note that the
- X * string is in static space. If you want to munge with it,
- X * make a copy.
- X */
- X
- Xchar *hostfrom(i)
- X int i;
- X{
- X struct sockaddr_in from;
- X int fromlen = sizeof(from);
- X struct hostent *host;
- X struct in_addr addr;
- X
- X if (getpeername(i, &from, &fromlen) < 0) {
- X perror("getpeername");
- X return NULL;
- X }
- X
- X addr = from.sin_addr;
- X if ((host = gethostbyaddr(&addr, sizeof(addr), AF_INET)) == NULL) {
- X debug("gethostbyaddr failed");
- X return NULL;
- X }
- X
- X return curhostname = host->h_name;
- X}
- X
- X
- X/*
- X * hostname() - returns curhostname
- X */
- X
- Xchar *hostname()
- X{
- X return curhostname;
- X}
- X
- X
- X/*
- X * new_player() - call this routine in your main loop to allow new
- X * players to join. returns a playerId or -1 if no one
- X * wants to join.
- X * if wait == 0, then put your process to sleep until
- X * someone new tries to connect.
- X */
- X
- Xint new_player(wait)
- X int wait; /* 0 - wait for activity, else don't wait */
- X{
- X fd_set readfds;
- X int j;
- X struct timeval *pWaitTime, waitTime;
- X
- X pWaitTime = &waitTime;
- X
- X if (0 == wait) {
- X pWaitTime = NEVER;
- X } else {
- X pWaitTime->tv_sec = SECONDSLIMIT;
- X pWaitTime->tv_usec = MICROSECONDSLIMIT;
- X }
- X
- X bcopy((char *) &active, (char *) &readfds, sizeof(active));
- X
- X FD_SET(s, &readfds);
- X
- X if (select(FD_SETSIZE, &readfds, NONE, NONE, pWaitTime) < 0) {
- X perror("select");
- X return -1;
- X }
- X if (FD_ISSET(s, &readfds)) {
- X if ((j = accept(s, IGNORE, (int *) 0)) < 0) {
- X return -1;
- X }
- X FD_SET(j, &active);
- X curhostname = hostfrom(j);
- X debug("Test Host=%s\n", curhostname);
- X return j;
- X } else {
- X return -1;
- X }
- X}
- X
- X
- X/*
- X * disconnect() - drop the player with the given id
- X */
- X
- Xint disconnect(id)
- X int id;
- X{
- X if (FD_ISSET(id, &active)) {
- X debug("** Just dropped %d\n", id);
- X FD_CLR(id, &active);
- X if (close(id) < 0) {
- X perror("close");
- X return 0;
- X }
- X } else {
- X debug("** Just tried to drop someone not connected\n");
- X return 0;
- X }
- X return 1;
- X}
- X
- X
- X/*
- X * read_player() - This routine returns the next string from the player
- X * connected to descriptor playerFd. If there is no
- X * input it returns the empty string. If the connection
- X * is lost the string LOST_CARRIER_MSG is returned.
- X * NOTE: control characters are replaced by spaces
- X * and it is null terminated at the first nl/cr
- X */
- X
- Xchar *read_player(playerFd)
- X int playerFd;
- X{
- X fd_set readfds;
- X struct timeval waitTime;
- X
- X waitTime.tv_sec = SECONDSLIMIT;
- X waitTime.tv_usec = MICROSECONDSLIMIT;
- X
- X bcopy((char *) &active, (char *) &readfds, sizeof(active));
- X
- X if (select(FD_SETSIZE, &readfds, NONE, NONE, &waitTime) < 0) {
- X perror("select");
- X return("");
- X }
- X
- X if (FD_ISSET(playerFd, &readfds)) {
- X int nbytes, i;
- X
- X nbytes = read(playerFd, cur_input, LINE_LEN);
- X if (nbytes < 0) {
- X perror("read");
- X disconnect(playerFd);
- X return(LOST_CARRIER_MSG);
- X } else if (nbytes == 0) {
- X disconnect(playerFd);
- X return(LOST_CARRIER_MSG);
- X } else {
- X/* Don't need control editing for(i=0; i<nbytes; ++i) {
- X if (iscntrl(cur_input[i])) {
- X if (cur_input[i]=='\n' ||
- X cur_input[i]=='\r')
- X cur_input[i] = '\n';
- X else
- X cur_input[i] = ' ';
- X }
- X }
- X*/
- X if (nbytes != LINE_LEN) {
- X cur_input[nbytes] = '\0';
- X } else {
- X cur_input[LINE_LEN - 1] = '\0';
- X }
- X
- X return((char *) cur_input);
- X }
- X }
- X return("");
- X}
- X
- X
- X/*
- X * write_player() - write to id, a string with the given length
- X */
- X
- Xint w_p(id, str, len)
- X int id, len;
- X char *str;
- X{
- X if (id > -1) {
- X if (!FD_ISSET(id, &active)) {
- X debug("** Tried to write to closed id #%d.\n", id);
- X return 0;
- X } else if (write(id, str, len) < 0) {
- X perror("Write");
- X return 0;
- X }
- X }
- X return 1;
- X}
- X
- X
- X
- X
- END_OF_FILE
- if test 8905 -ne `wc -c <'interface.c'`; then
- echo shar: \"'interface.c'\" unpacked with wrong size!
- fi
- # end of 'interface.c'
- fi
- if test -f 'types.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'types.h'\"
- else
- echo shar: Extracting \"'types.h'\" \(282 characters\)
- sed "s/^X//" >'types.h' <<'END_OF_FILE'
- Xtypedef struct {
- X char terrain;
- X int population;
- X int lastuse;
- X int troops;
- X int owner;
- X} hex;
- X
- Xtypedef struct {
- X int x;
- X int y;
- X} location;
- X
- Xtypedef struct {
- X int action;
- X int hexes;
- X int troops;
- X int population;
- X int citadels;
- X int live;
- X location start;
- X} player;
- X
- END_OF_FILE
- if test 282 -ne `wc -c <'types.h'`; then
- echo shar: \"'types.h'\" unpacked with wrong size!
- fi
- # end of 'types.h'
- fi
- echo shar: End of archive 2 \(of 2\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked both archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-